
#include "bsp_sgm415xx.h"
#include "bsp_sgm415xx_2.h"
#include "i2c2.h"
#include "bsp_uart.h"
#include "i2c_select.h"
#include "systick.h"
#include "bsp_gpio.h"
#include "bsp_sgm41513_i2c_2.h"

#ifdef __BSP_DEBUG__
    #define DEBUG_LOG(format, ...) printf(format, ##__VA_ARGS__)
//    #define BSP_LOG(format, ...)   printf(format, ##__VA_ARGS__)
#else
    #define DEBUG_LOG(format, ...)
#endif

#ifdef __BSP_DEBUG__
    #define BSP_LOG(format, ...) printf(format, ##__VA_ARGS__)
//    #define BSP_LOG(format, ...)   printf(format, ##__VA_ARGS__)
#else
    #define BSP_LOG(format, ...)
#endif


static struct sgm4154x_device sgm;


/**********************************************************
 *
 *   [I2C Slave Setting]
 *
 *********************************************************/
#define SGM4154x_REG_NUM    (0xF)

/* SGM4154x REG06 BOOST_LIM[5:4], uV */
//static const unsigned int BOOST_VOLT_LIMIT[] = {
//	4850000, 5000000, 5150000, 5300000		
//};
/* SGM4154x REG02 BOOST_LIM[7:7], uA */
#if (defined(__SGM41542_CHIP_ID__) || defined(__SGM41541_CHIP_ID__)|| defined(__SGM41543_CHIP_ID__)|| defined(__SGM41543D_CHIP_ID__))
static const unsigned int BOOST_CURRENT_LIMIT[] = {
    1200000, 2000000
};
#else
static const unsigned int BOOST_CURRENT_LIMIT[] = {
    500000, 1200000
};
#endif

#if (defined(__SGM41513_CHIP_ID__) || defined(__SGM41513A_CHIP_ID__) || defined(__SGM41513D_CHIP_ID__))

static const unsigned int IPRECHG_CURRENT_STABLE[] = {
    5000, 10000, 15000, 20000, 30000, 40000, 50000, 60000,
    80000, 100000, 120000, 140000, 160000, 180000, 200000, 240000
};

static const unsigned int ITERM_CURRENT_STABLE[] = {
    5000, 10000, 15000, 20000, 30000, 40000, 50000, 60000,
    80000, 100000, 120000, 140000, 160000, 180000, 200000, 240000
};
#endif




/**********************************************************
 *
 *   [I2C Function For Read/Write sgm4154x]
 *return 
0: success
-1:error
*********************************************************/
int __sgm4154x_read_byte_2(uint8_t reg, uint8_t *data)
{
    int ret;

    ret = com_i2cm_sgm415x_8bitread_2(SGM4154X_DEVICE_ADDR_2, reg, 1, data);
    
    if(!ret) 
    {
        BSP_LOG("i2c read fail: can't read from reg 0x%02X\n", reg);
        return -1; 
    }

    return 0;
}

/*
return 0 : success
    -1: fail
*/
int __sgm4154x_write_byte_2(int reg, uint8_t val)
{
    int32_t ret;

    ret = com_i2cm_sgm415x_8bitwrit_2(SGM4154X_DEVICE_ADDR_2, reg, 1, &val);
    if(!ret)
    {
        BSP_LOG("i2c write fail: can't write 0x%02X to reg 0x%02X: %d\n", val, reg, ret);
        return -1;
    }

    return 0;
}



int sgm4154x_read_reg_2(uint8_t reg, uint8_t *data)
{
    int ret;

    ret = __sgm4154x_read_byte_2(reg, data);

    return ret;
}


int sgm4154x_write_reg_2(uint8_t reg, uint8_t val)
{
    int ret;

    ret = __sgm4154x_write_byte_2(reg, val);

    if (ret)
        BSP_LOG("Failed: reg=%02X, ret=%d\n", reg, ret);

    return ret;
}


/*
return 0 : success
    -1: fail
*/
int sgm4154x_update_bits_2(uint8_t reg, uint8_t mask, uint8_t val)
{
    int ret;
    uint8_t tmp;

    ret = __sgm4154x_read_byte_2(reg, &tmp);
    if(ret)
    {
        BSP_LOG("read Failed: reg=%02X, ret=%d\n", reg, ret);
        goto out;
    }

    tmp &= ~mask;
    tmp |= val & mask;

    ret = __sgm4154x_write_byte_2(reg, tmp);

    if(ret)
    {
        BSP_LOG("write Failed: reg=%02X, ret=%d\n", reg, ret);
    }

out:
    return ret;
}

/**********************************************************
 *
 *   [Internal Function]
 *
 *********************************************************/
#if 1
static int sgm4154x_set_watchdog_timer_2(int time)
{
    int ret;
    uint8_t reg_val;

    if (time == 0)
        reg_val = SGM4154x_WDT_TIMER_DISABLE;
    else if (time == 40)
        reg_val = SGM4154x_WDT_TIMER_40S;
    else if (time == 80)
        reg_val = SGM4154x_WDT_TIMER_80S;
    else
        reg_val = SGM4154x_WDT_TIMER_160S;	

    ret = sgm4154x_update_bits_2(SGM4154x_CHRG_CTRL_5,SGM4154x_WDT_TIMER_MASK, reg_val);

    return ret;
}


int sgm4154x_get_term_curr_2(void)
{
    int ret;
    uint8_t reg_val;
    int curr;
    int offset = SGM4154x_TERMCHRG_I_MIN_uA;

    ret = sgm4154x_read_reg_2(SGM4154x_CHRG_CTRL_3, &reg_val);
    if (ret)
        return ret;

    reg_val &= SGM4154x_TERMCHRG_CUR_MASK;
    curr = reg_val * SGM4154x_TERMCHRG_CURRENT_STEP_uA + offset;
    return curr;
}

int sgm4154x_get_prechrg_curr_2(void)
{
    int ret;
    uint8_t reg_val;
    int curr;
    int offset = SGM4154x_PRECHRG_I_MIN_uA;

    ret = sgm4154x_read_reg_2(SGM4154x_CHRG_CTRL_3, &reg_val);
    if (ret)
        return ret;

    reg_val = (reg_val&SGM4154x_PRECHRG_CUR_MASK)>>4;
    curr = reg_val * SGM4154x_PRECHRG_CURRENT_STEP_uA + offset;
    return curr;
}

int sgm4154x_get_ichg_curr_2(void)
{
    int ret;
    uint8_t ichg;
    unsigned int curr;
    
    ret = sgm4154x_read_reg_2(SGM4154x_CHRG_CTRL_2, &ichg);
    if (ret)
        return ret;	

    ichg &= SGM4154x_ICHRG_I_MASK;
#if (defined(__SGM41513_CHIP_ID__) || defined(__SGM41513A_CHIP_ID__) || defined(__SGM41513D_CHIP_ID__))	
    if (ichg <= 0x8)
        curr = ichg * 5000;
    else if (ichg <= 0xF)
        curr = 40000 + (ichg - 0x8) * 10000;
    else if (ichg <= 0x17)
        curr = 110000 + (ichg - 0xF) * 20000;
    else if (ichg <= 0x20)
        curr = 270000 + (ichg - 0x17) * 30000;
    else if (ichg <= 0x30)
        curr = 540000 + (ichg - 0x20) * 60000;
    else if (ichg <= 0x3C)
        curr = 1500000 + (ichg - 0x30) * 120000;
    else
        curr = 3000000;
#else
    curr = ichg * SGM4154x_ICHRG_I_STEP_uA;
#endif	
    return curr;
}
#endif

static int sgm4154x_set_term_curr_2(int uA)
{
    uint8_t reg_val;
    int ret;
    
#if (defined(__SGM41513_CHIP_ID__) || defined(__SGM41513A_CHIP_ID__) || defined(__SGM41513D_CHIP_ID__))	
    
    for(reg_val = 1; reg_val < 16 && uA >= ITERM_CURRENT_STABLE[reg_val]; reg_val++)
        ;
    reg_val--;
#else
    if (uA < SGM4154x_TERMCHRG_I_MIN_uA)
        uA = SGM4154x_TERMCHRG_I_MIN_uA;
    else if (uA > SGM4154x_TERMCHRG_I_MAX_uA)
        uA = SGM4154x_TERMCHRG_I_MAX_uA;
    
    reg_val = (uA - SGM4154x_TERMCHRG_I_MIN_uA) / SGM4154x_TERMCHRG_CURRENT_STEP_uA;
#endif

    ret = sgm4154x_update_bits_2(SGM4154x_CHRG_CTRL_3,
                SGM4154x_TERMCHRG_CUR_MASK, reg_val);
    BSP_LOG("%s reg_val=0x%02X\r\n", __func__, reg_val);
    return ret;
}

int sgm4154x_set_prechrg_curr_2(int uA)
{
    uint8_t reg_val;
    int ret;
    
#if (defined(__SGM41513_CHIP_ID__) || defined(__SGM41513A_CHIP_ID__) || defined(__SGM41513D_CHIP_ID__))
    for(reg_val = 1; reg_val < 16 && uA >= IPRECHG_CURRENT_STABLE[reg_val]; reg_val++)
        ;
    reg_val--;
#else
    if (uA < SGM4154x_PRECHRG_I_MIN_uA)
        uA = SGM4154x_PRECHRG_I_MIN_uA;
    else if (uA > SGM4154x_PRECHRG_I_MAX_uA)
        uA = SGM4154x_PRECHRG_I_MAX_uA;

    reg_val = (uA - SGM4154x_PRECHRG_I_MIN_uA) / SGM4154x_PRECHRG_CURRENT_STEP_uA;
#endif
    reg_val = reg_val << 4;
    ret = sgm4154x_update_bits_2(SGM4154x_CHRG_CTRL_3,
                SGM4154x_PRECHRG_CUR_MASK, reg_val);
    BSP_LOG("%s reg_val=0x%02X\r\n",__func__,reg_val);
    return ret;
}


int sgm4154x_set_ichrg_curr_2(unsigned int uA)
{
    int ret;
    uint8_t reg_val;
    unsigned int uA_last;
    
    if (uA < SGM4154x_ICHRG_I_MIN_uA)
        uA = SGM4154x_ICHRG_I_MIN_uA;
    else if ( uA > sgm.init_data.max_ichg)
        uA = sgm.init_data.max_ichg;
    
#if (defined(__SGM41513_CHIP_ID__) || defined(__SGM41513A_CHIP_ID__) || defined(__SGM41513D_CHIP_ID__))
    if (uA <= 40000)
        reg_val = uA / 5000;	
    else if (uA <= 110000)
        reg_val = 0x08 + (uA -40000) / 10000;	
    else if (uA <= 270000)
        reg_val = 0x0F + (uA -110000) / 20000;	
    else if (uA <= 540000)
        reg_val = 0x17 + (uA -270000) / 30000;	
    else if (uA <= 1500000)
        reg_val = 0x20 + (uA -540000) / 60000;	
    else if (uA <= 2940000)
        reg_val = 0x30 + (uA -1500000) / 120000;
    else 
        reg_val = 0x3d;
#else

    reg_val = uA / SGM4154x_ICHRG_I_STEP_uA;
#endif
    ret = sgm4154x_update_bits_2(SGM4154x_CHRG_CTRL_2,
                SGM4154x_ICHRG_I_MASK, reg_val);
    uA_last = reg_val*5;
    
    if (uA_last)
    {;}
    
    BSP_LOG("%s %02X reg_val=0x%02X  %02X ICHRG=%d\r\n",__func__,SGM4154x_CHRG_CTRL_2,reg_val,SGM4154x_ICHRG_I_MASK, uA_last);
    return ret;
}

int sgm4154x_set_chrg_volt_2(unsigned int chrg_volt)
{
    int ret;
    uint8_t reg_val;
    uint8_t reg_val1;
    
    reg_val = (chrg_volt-SGM4154x_VREG_V_MIN_uV) / SGM4154x_VREG_V_STEP_uV;
    reg_val = reg_val<<3;
    ret = sgm4154x_update_bits_2(SGM4154x_CHRG_CTRL_4,
                SGM4154x_VREG_V_MASK, reg_val);
    ret = __sgm4154x_read_byte_2(SGM4154x_CHRG_CTRL_4, &reg_val1);
    
    BSP_LOG("%s reg_val=0x%02X 0x%02X \r\n",__func__,reg_val,reg_val1);
    return ret;
}

int sgm4154x_get_chrg_volt_2(unsigned int *volt)
{
    int ret;
    uint8_t vreg_val;
    
    ret = sgm4154x_read_reg_2(SGM4154x_CHRG_CTRL_4, &vreg_val);
    if (ret)
        return ret;	

    vreg_val = (vreg_val & SGM4154x_VREG_V_MASK)>>3;

    if (15 == vreg_val)
        *volt = 4352000; /* default */
    else if (vreg_val < 25)	
        *volt = vreg_val*SGM4154x_VREG_V_STEP_uV + SGM4154x_VREG_V_MIN_uV;	

    return 0;
}


int sgm4154x_get_vindpm_offset_os_2(void)
{
    int ret;
    uint8_t reg_val;

    ret = sgm4154x_read_reg_2(SGM4154x_CHRG_CTRL_f, &reg_val);
    if (ret)
        return ret;	

    reg_val = reg_val & SGM4154x_VINDPM_OS_MASK;	

    return reg_val;
}

int sgm4154x_set_vindpm_offset_os_2(uint8_t offset_os)
{
    int ret;	
    
    ret = sgm4154x_update_bits_2(SGM4154x_CHRG_CTRL_f,
                SGM4154x_VINDPM_OS_MASK, offset_os);
    
    if (ret){
        BSP_LOG("%s fail\n",__func__);
        return ret;
    }
    
    return ret;
}
int sgm4154x_set_input_volt_lim_2(unsigned int vindpm)
{
    int ret;
    unsigned int offset;
    uint8_t reg_val;
    uint8_t os_val;

    if (vindpm < SGM4154x_VINDPM_V_MIN_uV ||
        vindpm > SGM4154x_VINDPM_V_MAX_uV)
        return -EINVAL;	
    
    if (vindpm < 5900000){
        os_val = 0;
        offset = 3900000;
    }		
    else if (vindpm >= 5900000 && vindpm < 7500000){
        os_val = 1;
        offset = 5900000; //uv
    }		
    else if (vindpm >= 7500000 && vindpm < 10500000){
        os_val = 2;
        offset = 7500000; //uv
    }		
    else{
        os_val = 3;
        offset = 10500000; //uv
    }		
    
    sgm4154x_set_vindpm_offset_os_2(os_val);
    reg_val = (vindpm - offset) / SGM4154x_VINDPM_STEP_uV;	

    ret = sgm4154x_update_bits_2(SGM4154x_CHRG_CTRL_6,
                SGM4154x_VINDPM_V_MASK, reg_val); 
    BSP_LOG("%s reg_val=0x%02X\r\n",__func__,reg_val);
    return ret;
}
#if 0
static int sgm4154x_get_input_volt_lim_2(struct sgm4154x_device *sgm)
{
    int ret;
    int offset;
    u8 vlim;
    int temp;

    ret = sgm4154x_read_reg_2(sgm, SGM4154x_CHRG_CTRL_6, &vlim);
    if (ret)
        return ret;
    
    temp = sgm4154x_get_vindpm_offset_os_2(sgm);
    if (0 == temp)
        offset = 3900000; //uv
    else if (1 == temp)
        offset = 5900000;
    else if (2 == temp)
        offset = 7500000;
    else if (3 == temp)
        offset = 10500000;
    
    temp = offset + (vlim & 0x0F) * SGM4154x_VINDPM_STEP_uV;
    return temp;
}
#endif

int sgm4154x_set_input_curr_lim_2(unsigned int iindpm)
{
    int ret;
    uint8_t reg_val;

#if (defined(__SGM41513_CHIP_ID__) || defined(__SGM41513A_CHIP_ID__) || defined(__SGM41513D_CHIP_ID__))
    reg_val = (iindpm-SGM4154x_IINDPM_I_MIN_uA) / SGM4154x_IINDPM_STEP_uA;
#else		
    if (iindpm >= SGM4154x_IINDPM_I_MIN_uA && iindpm <= 3100000)//default
        reg_val = (iindpm-SGM4154x_IINDPM_I_MIN_uA) / SGM4154x_IINDPM_STEP_uA;
    else if (iindpm > 3100000 && iindpm < SGM4154x_IINDPM_I_MAX_uA)
        reg_val = 0x1E;
    else
        reg_val = SGM4154x_IINDPM_I_MASK;
#endif
    ret = sgm4154x_update_bits_2(SGM4154x_CHRG_CTRL_0,
                SGM4154x_IINDPM_I_MASK, reg_val);
    BSP_LOG("%s reg_val=0x%02X\r\n",__func__,reg_val);
    
    return ret;
}



int sgm4154x_get_input_curr_lim_2(unsigned int *ilim)
{
    int ret;	
    uint8_t reg_val;

    ret = sgm4154x_read_reg_2(SGM4154x_CHRG_CTRL_0, &reg_val);
    if (ret)
        return ret;	
    if (SGM4154x_IINDPM_I_MASK == (reg_val & SGM4154x_IINDPM_I_MASK))
        *ilim =  SGM4154x_IINDPM_I_MAX_uA;
    else
        *ilim = (reg_val & SGM4154x_IINDPM_I_MASK)*SGM4154x_IINDPM_STEP_uA + SGM4154x_IINDPM_I_MIN_uA;

    return 0;
}

int sgm4154x_get_state_2(struct sgm4154x_state *state)
{
    uint8_t chrg_stat;
    uint8_t fault;
    uint8_t chrg_param_0,chrg_param_1,chrg_param_2;
    int ret;

    ret = sgm4154x_read_reg_2(SGM4154x_CHRG_STAT, &chrg_stat);
    if (ret){
        ret = sgm4154x_read_reg_2(SGM4154x_CHRG_STAT, &chrg_stat);
        if (ret){
            BSP_LOG("%s read SGM4154x_CHRG_STAT fail\n",__func__);
            return ret;
        }
    }
    state->chrg_type = chrg_stat & SGM4154x_VBUS_STAT_MASK;
    state->chrg_stat = chrg_stat & SGM4154x_CHG_STAT_MASK;
    state->online = !!(chrg_stat & SGM4154x_PG_STAT);
    state->therm_stat = !!(chrg_stat & SGM4154x_THERM_STAT);
    state->vsys_stat = !!(chrg_stat & SGM4154x_VSYS_STAT);
    
    BSP_LOG("%s chrg_stat=0x%02X chrg_type =%d,chrg_stat =%d online = %d\n",__func__,chrg_stat,state->chrg_type,state->chrg_stat,state->online);
    

    ret = sgm4154x_read_reg_2(SGM4154x_CHRG_FAULT, &fault);
    if (ret){
        BSP_LOG("%s read SGM4154x_CHRG_FAULT fail\n",__func__);
        return ret;
    }
    state->chrg_fault = fault;	
    state->ntc_fault = fault & SGM4154x_TEMP_MASK;
    state->health = state->ntc_fault;
    
    BSP_LOG("err: %s 0x%02X chrg_fault =%d,ntc_fault =%d health = %d\n",__func__,fault,state->chrg_fault,state->ntc_fault,state->ntc_fault);
    
    
    
    ret = sgm4154x_read_reg_2(SGM4154x_CHRG_CTRL_0, &chrg_param_0);
    if (ret){
        BSP_LOG("%s read SGM4154x_CHRG_CTRL_0 fail\n",__func__);
        return ret;
    }
    state->hiz_en = !!(chrg_param_0 & SGM4154x_HIZ_EN);
    
    ret = sgm4154x_read_reg_2(SGM4154x_CHRG_CTRL_5, &chrg_param_1);
    if (ret){
        BSP_LOG("%s read SGM4154x_CHRG_CTRL_5 fail\n",__func__);
        return ret;
    }
    state->term_en = !!(chrg_param_1 & SGM4154x_TERM_EN);
    
    ret = sgm4154x_read_reg_2(SGM4154x_CHRG_CTRL_a, &chrg_param_2);
    if (ret){
        BSP_LOG("%s read SGM4154x_CHRG_CTRL_a fail\n",__func__);
        return ret;
    }
    state->vbus_gd = !!(chrg_param_2 & SGM4154x_VBUS_GOOD);

    return 0;
}

int sgm4154x_set_hiz_en_2(bool hiz_en)
{
    uint8_t reg_val;

    reg_val = hiz_en ? SGM4154x_HIZ_EN : 0;

    return sgm4154x_update_bits_2(SGM4154x_CHRG_CTRL_0,
                SGM4154x_HIZ_EN, reg_val);
}

int sgm4154x_enable_charger_2(void)
{
    int ret;
    
    ret = sgm4154x_update_bits_2(SGM4154x_CHRG_CTRL_1, SGM4154x_CHRG_EN,
                    SGM4154x_CHRG_EN);
    
    return ret;
}

int sgm4154x_disable_charger_2(void)
{
    int ret;
    
    ret = sgm4154x_update_bits_2(SGM4154x_CHRG_CTRL_1, SGM4154x_CHRG_EN, 0);
    return ret;
}




/********************************************************************************
*
*    充电控制
*
********************************************************************************/
/*
return 0 : success
    -1: fail
*/
int sgm4154x_charging_switch_2(bool enable)
{
    int ret;

    if (enable)
        ret = sgm4154x_enable_charger_2();
    else
        ret = sgm4154x_disable_charger_2();
    return ret;
}

int sgm4154x_set_recharge_volt_2(int mV)
{
    uint8_t reg_val;
    int ret;
    
    reg_val = (mV - SGM4154x_VRECHRG_OFFSET_mV) / SGM4154x_VRECHRG_STEP_mV;

    ret = sgm4154x_update_bits_2(SGM4154x_CHRG_CTRL_4,
                SGM4154x_VRECHARGE, reg_val);
    BSP_LOG("%s reg_val=0x%02X\r\n",__func__,reg_val);
    return ret;
}

int sgm4154x_set_wdt_rst_2(bool is_rst)
{
    uint8_t val;
    
    if (is_rst)
        val = SGM4154x_WDT_RST_MASK;
    else
        val = 0;
    return sgm4154x_update_bits_2(SGM4154x_CHRG_CTRL_1,
                SGM4154x_WDT_RST_MASK, val);	
}

/**********************************************************
 *
 *   [Internal Function]
 *
 *********************************************************/
int sgm4154x_dump_register_2(void)
{

    unsigned char i = 0;
    unsigned int ret = 0;
    unsigned char sgm4154x_reg[SGM4154x_REG_NUM] = { 0 }; 
    
    for (i = 0; i < SGM4154x_REG_NUM+1; i++) {
        ret = sgm4154x_read_reg_2(i, &sgm4154x_reg[i]);
        if (ret == 0) {
            BSP_LOG("[sgm4154x] i2c transfor error\n");
            return 1;
        }
        BSP_LOG("%s,[0x%x]=0x%x ",__func__, i, sgm4154x_reg[i]);
    }
    
    return 0;
}


/**********************************************************
 *
 *   [Internal Function]
 *   查询ID
 *********************************************************/
int sgm4154x_hw_chipid_detect_2(void)
{
    int ret = 0;
    uint8_t val = 0;
    ret = sgm4154x_read_reg_2(SGM4154x_CHRG_CTRL_b,&val);
    if (ret < 0)
    {
        BSP_LOG("[%s] read SGM4154x_CHRG_CTRL_b fail\n", __func__);
        return ret;
    }		
    val = val & SGM4154x_PN_MASK;
    BSP_LOG("[%s] Reg[0x0B]=0x%x\n", __func__,val);
    
    return val;
}

int sgm4154x_reset_watch_dog_timer_2(void)
{
    int ret;
    
    BSP_LOG("charging_reset_watch_dog_timer\n");

    ret = sgm4154x_set_wdt_rst_2(0x1);	/* RST watchdog */	

    return ret;
}


int sgm4154x_set_en_timer_2(void)
{
    int ret;	

    ret = sgm4154x_update_bits_2(SGM4154x_CHRG_CTRL_5,
                SGM4154x_SAFETY_TIMER_EN, SGM4154x_SAFETY_TIMER_EN);

    return ret;
}

int sgm4154x_set_disable_timer_2(void)
{
    int ret;	

    ret = sgm4154x_update_bits_2(SGM4154x_CHRG_CTRL_5,
                SGM4154x_SAFETY_TIMER_EN, 0);

    return ret;
}

int sgm4154x_enable_safetytimer_2(bool en)
{
    int ret = 0;

    if (en)
        ret = sgm4154x_set_en_timer_2();
    else
        ret = sgm4154x_set_disable_timer_2();
    return ret;
}

int sgm4154x_get_is_safetytimer_enable_2(bool *en)
{
    int ret = 0;
    uint8_t val = 0;
    
    ret = sgm4154x_read_reg_2(SGM4154x_CHRG_CTRL_5,&val);
    if (ret < 0)
    {
        BSP_LOG("[%s] read SGM4154x_CHRG_CTRL_5 fail\n", __func__);
        return ret;
    }
    *en = !!(val & SGM4154x_SAFETY_TIMER_EN);
    return 0;
}

#if 0
static int sgm4154x_charger_get_property(struct power_supply *psy,
                enum power_supply_property psp,
                union power_supply_propval *val)
{
    struct sgm4154x_device *sgm = power_supply_get_drvdata(psy);
    struct sgm4154x_state state;
    int ret = 0;

//	mutex_lock(&sgm->lock);
    //ret = sgm4154x_get_state_2(sgm, &state);
    state = sgm->state;
    mutex_unlock(&sgm->lock);
    if (ret)
        return ret;

    switch (psp) {
    case POWER_SUPPLY_PROP_STATUS:
        if (!state.chrg_type || (state.chrg_type == SGM4154x_OTG_MODE))
            val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
        else if (!state.chrg_stat)
            val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
        else if (state.chrg_stat == SGM4154x_TERM_CHRG)
            val->intval = POWER_SUPPLY_STATUS_FULL;
        else
            val->intval = POWER_SUPPLY_STATUS_CHARGING;
        break;
    case POWER_SUPPLY_PROP_CHARGE_TYPE:
        switch (state.chrg_stat) {		
        case SGM4154x_PRECHRG:
            val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
            break;
        case SGM4154x_FAST_CHRG:
            val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST;
            break;		
        case SGM4154x_TERM_CHRG:
            val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
            break;
        case SGM4154x_NOT_CHRGING:
            val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
            break;
        default:
            val->intval = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
        }
        break;
    case POWER_SUPPLY_PROP_MANUFACTURER:
        val->strval = SGM4154x_MANUFACTURER;
        break;

    case POWER_SUPPLY_PROP_MODEL_NAME:
        val->strval = SGM4154x_NAME;
        break;

    case POWER_SUPPLY_PROP_ONLINE:
        val->intval = state.online;
        break;
    case POWER_SUPPLY_PROP_PRESENT:
        val->intval = state.vbus_gd;
        break;
    case POWER_SUPPLY_PROP_TYPE:
        val->intval = sgm4154x_power_supply_desc.type;
        break;
    case POWER_SUPPLY_PROP_USB_TYPE:
        //val->intval = get_charger_type(sgm);
        break;

    case POWER_SUPPLY_PROP_HEALTH:
        if (state.chrg_fault & 0xF8)
            val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
        else
            val->intval = POWER_SUPPLY_HEALTH_GOOD;

        switch (state.health) {
        case SGM4154x_TEMP_HOT:
            val->intval = POWER_SUPPLY_HEALTH_HOT;
            break;
        case SGM4154x_TEMP_WARM:
            val->intval = POWER_SUPPLY_HEALTH_WARM;
            break;
        case SGM4154x_TEMP_COOL:
            val->intval = POWER_SUPPLY_HEALTH_COOL;
            break;
        case SGM4154x_TEMP_COLD:
            val->intval = POWER_SUPPLY_HEALTH_COLD;
            break;
        }
        break;

    case POWER_SUPPLY_PROP_VOLTAGE_NOW:
        //val->intval = state.vbus_adc;
        break;

    case POWER_SUPPLY_PROP_CURRENT_NOW:
        //val->intval = state.ibus_adc;
        break;

/*	case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT:
        ret = sgm4154x_get_input_volt_lim_2(sgm);
        if (ret < 0)
            return ret;

        val->intval = ret;
        break;*/

    case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:		
        break;

    case POWER_SUPPLY_PROP_CHARGING_ENABLED:
        val->intval = !state.hiz_en;
        break;

    default:
        return -EINVAL;
    }

    return ret;
}
#endif

#if 0
static void charger_detect_work_func(struct work_struct *work)
{
    struct delayed_work *charge_detect_delayed_work = NULL;
    struct sgm4154x_device * sgm = NULL;
    //static int charge_type_old = 0;
    int curr_in_limit = 0;	
    struct sgm4154x_state state;	
    int ret;
    
    charge_detect_delayed_work = container_of(work, struct delayed_work, work);
    if(charge_detect_delayed_work == NULL) {
        BSP_LOG("Cann't get charge_detect_delayed_work\n");
        return ;
    }
    sgm = container_of(charge_detect_delayed_work, struct sgm4154x_device, charge_detect_delayed_work);
    if(sgm == NULL) {
        BSP_LOG("Cann't get sgm4154x_device\n");
        return ;
    }

    if (!sgm->charger_wakelock->active)
        __pm_stay_awake(sgm->charger_wakelock);

    ret = sgm4154x_get_state_2(sgm, &state);
    mutex_lock(&sgm->lock);
    sgm->state = state;	
    mutex_unlock(&sgm->lock);	
    
    if(!sgm->state.vbus_gd) {
        dev_err(sgm->dev, "Vbus not present, disable charge\n");
        sgm4154x_disable_charger_2(sgm);
        goto err;
    }
    if(!state.online)
    {
        dev_err(sgm->dev, "Vbus not online\n");		
        goto err;
    }	
#if (defined(__SGM41542_CHIP_ID__)|| defined(__SGM41516D_CHIP_ID__)|| defined(__SGM41543D_CHIP_ID__))
    switch(sgm->state.chrg_type) {
        case SGM4154x_USB_SDP:
            BSP_LOG("SGM4154x charger type: SDP\n");
            curr_in_limit = 500000;
            break;

        case SGM4154x_USB_CDP:
            BSP_LOG("SGM4154x charger type: CDP\n");
            curr_in_limit = 1500000;
            break;

        case SGM4154x_USB_DCP:
            BSP_LOG("SGM4154x charger type: DCP\n");
            curr_in_limit = 2000000;
            break;

        case SGM4154x_UNKNOWN:
            BSP_LOG("SGM4154x charger type: UNKNOWN\n");
            curr_in_limit = 500000;
            break;	

        default:
            BSP_LOG("SGM4154x charger type: default\n");
            //curr_in_limit = 500000;
            //break;
            return;
    }

    //set charge parameters
    dev_err(sgm->dev, "Update: curr_in_limit = %d\n", curr_in_limit);
    sgm4154x_set_input_curr_lim_2(sgm->chg_dev, curr_in_limit);
    
#endif
    //enable charge
    sgm4154x_enable_charger_2(sgm);
    sgm4154x_dump_register_2(sgm->chg_dev);
    power_supply_changed(sgm->charger);	
    return;
err:
    //release wakelock
    power_supply_changed(sgm->charger);	
    dev_err(sgm->dev, "Relax wakelock\n");
    __pm_relax(sgm->charger_wakelock);
    return;
}
#endif



#if 1
int sgm4154x_hw_init_2(uint32_t I_uA, uint32_t vindpm)
{
    int ret = 0;	
    struct power_supply_battery_info bat_info = {0};	

    bat_info.constant_charge_current_max_ua =  I_uA ;

    bat_info.constant_charge_voltage_max_uv = SGM4154x_VREG_V_DEF_uV;

    bat_info.precharge_current_ua = SGM4154x_PRECHRG_I_DEF_uA;

    bat_info.charge_term_current_ua = SGM4154x_TERMCHRG_I_DEF_uA;

    sgm.init_data.max_ichg = SGM4154x_ICHRG_I_MAX_uA;

    sgm.init_data.max_vreg = SGM4154x_VREG_V_MAX_uV;
    
    sgm.init_data.vlim = vindpm ; //SGM4154x_VINDPM_DEF_uV;
    
    sgm.init_data.ilim = SGM4154x_IINDPM_DEF_uA;
    

sgm4154x_set_JEITA_VSET_H_state_2(ENABLE);

    ret = sgm4154x_set_ichrg_curr_2(bat_info.constant_charge_current_max_ua);
    if (ret)
        goto err_out;

    ret = sgm4154x_set_prechrg_curr_2(bat_info.precharge_current_ua);
    if (ret)
        goto err_out;

    ret = sgm4154x_set_chrg_volt_2(bat_info.constant_charge_voltage_max_uv);
    if (ret)
        goto err_out;

    ret = sgm4154x_set_term_curr_2(bat_info.charge_term_current_ua);
    if (ret)
        goto err_out;

    ret = sgm4154x_set_input_volt_lim_2(sgm.init_data.vlim);
    if (ret)
        goto err_out;

    ret = sgm4154x_set_input_curr_lim_2(sgm.init_data.ilim);
    if (ret)
        goto err_out;
    #if 0
        ret = sgm4154x_set_vac_ovp(sgm); //14V
        if (ret)
            goto err_out;	
    #endif
    ret = sgm4154x_set_recharge_volt_2(200);//100~200mv
    if (ret)
        goto err_out;

    ret = sgm4154x_set_watchdog_timer_2(SGM4154x_WDT_TIMER_DISABLE);
    
    BSP_LOG("ichrg_curr:%d prechrg_curr:%d chrg_vol:%d"
        " term_curr:%d input_curr_lim:%d",
        bat_info.constant_charge_current_max_ua,
        bat_info.precharge_current_ua,
        bat_info.constant_charge_voltage_max_uv,
        bat_info.charge_term_current_ua,
        sgm.init_data.ilim);

    return 0;

err_out:
    return ret;

}
#endif

#if 1
int sgm4154x_parse_dt_2(void)
{	
    sgm.init_data.vlim = SGM4154x_VINDPM_DEF_uV;

    if (sgm.init_data.vlim > SGM4154x_VINDPM_V_MAX_uV ||
        sgm.init_data.vlim < SGM4154x_VINDPM_V_MIN_uV)
        return -EINVAL;

        sgm.init_data.ilim = SGM4154x_IINDPM_DEF_uA;

    if (sgm.init_data.ilim > SGM4154x_IINDPM_I_MAX_uA ||
        sgm.init_data.ilim < SGM4154x_IINDPM_I_MIN_uA)
        return -EINVAL;

    return 0;
}
#endif

int sgm4154x_enable_vbus_2(void)
{	
    int ret = 0;

    ret = sgm4154x_update_bits_2(SGM4154x_CHRG_CTRL_1, SGM4154x_OTG_EN,
                    SGM4154x_OTG_EN);
    return ret;
}

int sgm4154x_disable_vbus_2(void)
{
    int ret = 0;

    ret = sgm4154x_update_bits_2(SGM4154x_CHRG_CTRL_1, SGM4154x_OTG_EN,
                    0);

    return ret;
}

int sgm4154x_is_enabled_vbus_2(void)
{
    uint8_t temp = 0;

    sgm4154x_read_reg_2(SGM4154x_CHRG_CTRL_1, &temp);
    return (temp&SGM4154x_OTG_EN)? 1 : 0;
}

int sgm4154x_enable_otg_2(bool en)
{
    int ret = 0;

    BSP_LOG("%s en = %d\n", __func__, en);
    if (en) {
        ret = sgm4154x_enable_vbus_2();
    } else {
        ret = sgm4154x_disable_vbus_2();
    }
    return ret;
}

#if 0
static int sgm4154x_set_boost_voltage_limit_2(struct charger_device
        *chg_dev, u32 uV)
{	
    int ret = 0;
    char reg_val = -1;
    int i = 0;
    struct sgm4154x_device *sgm = charger_get_data(chg_dev);
    
    while(i<4){
        if (uV == BOOST_VOLT_LIMIT[i]){
            reg_val = i;
            break;
        }
        i++;
    }
    if (reg_val < 0)
        return reg_val;
    reg_val = reg_val << 4;
    ret = sgm4154x_update_bits_2(sgm, SGM4154x_CHRG_CTRL_6,
                SGM4154x_BOOSTV, reg_val);

    return ret;
}
#endif

int sgm4154x_set_boost_current_limit_2(uint32_t uA)
{	
    int ret = 0;
//	struct sgm4154x_device *sgm = charger_get_data(chg_dev);
    
    if (uA == BOOST_CURRENT_LIMIT[0]){
        ret = sgm4154x_update_bits_2(SGM4154x_CHRG_CTRL_2, SGM4154x_BOOST_LIM,
                    0); 
    }
        
    else if (uA == BOOST_CURRENT_LIMIT[1]){
        ret = sgm4154x_update_bits_2(SGM4154x_CHRG_CTRL_2, SGM4154x_BOOST_LIM,
                    BIT(7)); 
    }
    return ret;
}


int sgm4154x_vbus_regulator_register_2(void)
{

    int ret = 0;

    return ret;
}


int sgm4154x_driver_probe_2(void)
{
    int ret = 0;
    
    BSP_LOG("[%s]\n", __func__);

    
    ret = sgm4154x_hw_chipid_detect_2();
    if (ret != SGM4154x_PN_ID){
        BSP_LOG("[%s] device not found !!!\n", __func__);
        return ret;
    }	
    
    ret = sgm4154x_hw_init_2(SGM4154x_ICHRG_I_DEF_uA,SGM4154x_VINDPM_DEF_uV);
    if (ret) {
        BSP_LOG("Cannot initialize the chip.\n");
        return ret;
    }
    
    ret = sgm4154x_vbus_regulator_register_2();
    
    return ret;

}


void sgm4154x_charger_shutdown_2(void)
{
    int ret = 0;

    ret = sgm4154x_disable_charger_2();
    if (ret) {
        BSP_LOG("Failed to disable charger, ret = %d\n", ret);
    }
    BSP_LOG("sgm4154x_charger_shutdown_2\n");
}


int sgm4154x_switch_channel_charge_2(uint8_t chnl, bool enable)
{
    int ret;

    ret = sgm4154x_charging_switch_2(enable);

    return ret;    
}

void all_channel_charge_enable_2(void)
{
    sgm4154x_charging_switch_2(1);
}

void sgm415xx_all_channel_init_2(uint32_t I_uA)
{
    uint8_t i;
    int ret = 0;
    uint32_t vindpm;

    vindpm = SGM4154x_VINDPM_DEF_uV;  //SGM4154x_VINDPM_9v_DEF_uV

    ret = sgm4154x_hw_init_2(I_uA,vindpm);
    if (ret) {
        printf("[%d]Cannot initialize the chip.\n",i);
    }
    else
    {
        sgm4154x_charging_switch_2(1);  //初始化打开充电软件开关
    }

    printf("chip[%d] is initialize , current=%d\r\n",i,I_uA);
}

int sgm415xx_channel_init_2(uint8_t chanl, uint32_t I_uA)
{
    int ret = 0;
    uint32_t vindpm;

    vindpm = SGM4154x_VINDPM_DEF_uV;  // SGM4154x_VINDPM_9v_DEF_uV

    ret = sgm4154x_hw_init_2(I_uA, vindpm);
    if (ret) 
    {
            BSP_LOG("sgm415xx[%d]Cannot initialize the chip.\n",chanl);
            return -1;
    }
    else
    {
        sgm4154x_charging_switch_2(1);  //初始化打开充电软件开关
    }

    return 0;
}

int sgm415xx_channel_set_ichrg_curr_2(uint8_t chanl,uint32_t I_uA)
{
    int ret = 0;

    ret =  sgm4154x_set_ichrg_curr_2(I_uA);
    if (ret) 
    {
            BSP_LOG("sgm415xx[%d]Cannot set ichrg curr.\n",chanl);
            return -1;
    }
    
    return ret;
}


int sgm4154x_get_chrg_stat_2(uint8_t *stat)
{
    uint8_t chrg_stat;
    int ret;

    ret = sgm4154x_read_reg_2(SGM4154x_CHRG_STAT, &chrg_stat);
    if (ret){
        ret = sgm4154x_read_reg_2(SGM4154x_CHRG_STAT, &chrg_stat);
        if (ret){
            BSP_LOG("%s read SGM4154x_CHRG_STAT fail\n",__func__);
            return ret;
        }
    } 
    
    *stat = chrg_stat & SGM4154x_CHG_STAT_MASK;
    
    return 0; 
}


void sgm415xx_err_pro_2(void)
{
    uint8_t i;
    int ret;
    
    ret = sgm415xx_channel_init_2(i, SGM4154x_ICHRG_I_DEF_uA_min);
    if (!ret) 
    {
        BSP_LOG("chip[%d] is initialize , current=%d\r\n", i, SGM4154x_ICHRG_I_DEF_uA_min);
    }    
}

int sgm4154x_set_JEITA_VSET_H_state_2(uint8_t en)
{
    return sgm4154x_update_bits_2(SGM4154x_CHRG_CTRL_7, JEITA_VSET_H,
                                JEITA_VSET_H);
}



